home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / ReqMach.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  10KB  |  333 lines

  1. /* * Last edited: Dec 19 11:03 1991 (mallet) */
  2. /*
  3.  * $Id: ReqMach.c,v 1.2.1.2 1992/01/02 11:03:30 mallet Exp $
  4.  * 
  5.  * Copyright 1991 Lionel Mallet
  6.  * 
  7.  * Permission to use, copy, modify, distribute, and sell this software and its
  8.  * documentation for any purpose is hereby granted without fee, provided that
  9.  * the above copyright notice appears in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of Lionel MALLET not be used in
  12.  * advertising or publicity pertaining to distribution of the software
  13.  * without specific, written prior permission.  Lionel MALLET makes no
  14.  * representations about the suitability of this software for any
  15.  * purpose.  It is provided "as is" without express or implied warranty.
  16.  *
  17.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  18.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  20.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  21.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  *  This software is opened and free. Furthermore, everybody is kindly
  26.  * invited to participate to improve it for the benefit of all.
  27.  * Improvements can be new features, bugs fixes and porting issues
  28.  * resolution.
  29.  *
  30.  * Author:  Lionel Mallet, SIMULOG
  31.  */
  32.  
  33. /*
  34.  * $XConsortium: ReqMach.c,v 1.1 90/06/09 20:20:41 dmatic Exp $
  35.  *
  36.  * Copyright 1989 Massachusetts Institute of Technology
  37.  *
  38.  * Permission to use, copy, modify, distribute, and sell this software and its
  39.  * documentation for any purpose is hereby granted without fee, provided that
  40.  * the above copyright notice appear in all copies and that both that
  41.  * copyright notice and this permission notice appear in supporting
  42.  * documentation, and that the name of M.I.T. not be used in advertising or
  43.  * publicity pertaining to distribution of the software without specific,
  44.  * written prior permission.  M.I.T. makes no representations about the
  45.  * suitability of this software for any purpose.  It is provided "as is"
  46.  * without express or implied warranty.
  47.  *
  48.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  49.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  50.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  51.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  52.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  53.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  54.  *
  55.  * Author:  Davor Matic, MIT X Consortium
  56.  */
  57.  
  58.  
  59.  
  60. #include <X11/IntrinsicP.h>
  61. #include <X11/Xmu/Converters.h>
  62. #include <X11/StringDefs.h>
  63. #include <X11/Xatom.h>
  64. #include <X11/Xos.h>
  65. #include <X11/Xfuncs.h>
  66. #include "PixmapP.h"
  67.     
  68. #include <stdio.h>
  69. #include <math.h>
  70.  
  71. #define XtStrlen(s)                   ((s) ? strlen(s) : 0)
  72. #define abs(x)                        (((x) > 0) ? (x) : -(x))
  73. #define min(x, y)                     (((x) < (y)) ? (x) : (y))
  74. #define max(x, y)                     (((x) > (y)) ? (x) : (y))
  75.  
  76.  
  77. /*****************************************************************************\
  78.  * Request Machine: stacks up and handles requests from application calls.   * 
  79. \*****************************************************************************/
  80.  
  81. /*
  82.  * Searches for a request record of a request specified by its name.
  83.  * Returns a pointer to the record or NULL if the request was not found.
  84.  */
  85. PWRequestRec *FindRequest(name)
  86.     PWRequest name;
  87. {
  88.     int i;
  89.  
  90.     for (i = 0; i < pixmapClassRec.pixmap_class.num_requests; i++)
  91.     if (!strcmp(name, pixmapClassRec.pixmap_class.requests[i].name))
  92.         return &pixmapClassRec.pixmap_class.requests[i];
  93.     
  94.     return NULL;
  95. }
  96.  
  97. /*
  98.  * Adds a request to the request stack and does proper initializations.
  99.  * Returns TRUE if the request was found and FALSE otherwise.
  100.  */
  101. #if NeedFunctionPrototypes
  102. Boolean PWAddRequest(Widget w, PWRequest name, Boolean trap, 
  103.              XtPointer call_data, Cardinal call_data_size)
  104. #else
  105. Boolean PWAddRequest(w, name, trap, call_data, call_data_size)
  106.     Widget    w;
  107.     PWRequest name;
  108.     Boolean   trap;
  109.     XtPointer   call_data;
  110.     Cardinal  call_data_size;
  111. #endif
  112. {
  113.     PixmapWidget PW = (PixmapWidget) w;
  114.     PWRequestRec *request;
  115.     
  116.     if(request = FindRequest(name)) {
  117.     if (_PWDEBUG)
  118.       fprintf(stderr, "Adding... Cardinal: %d\n", PW->pixmap.cardinal + 1);
  119.  
  120.     PW->pixmap.request_stack = (PWRequestStack *)
  121.         XtRealloc((char *)PW->pixmap.request_stack,
  122.          (Cardinal)((++PW->pixmap.cardinal + 1) * sizeof(PWRequestStack)));
  123.     
  124.     PW->pixmap.request_stack[PW->pixmap.cardinal].request = request;
  125.     PW->pixmap.request_stack[PW->pixmap.cardinal].status = 
  126.         XtMalloc(request->status_size);
  127.     PW->pixmap.request_stack[PW->pixmap.cardinal].trap = trap;
  128.     PW->pixmap.request_stack[PW->pixmap.cardinal].call_data = 
  129.         XtMalloc(call_data_size);
  130.     bcopy(call_data, 
  131.           PW->pixmap.request_stack[PW->pixmap.cardinal].call_data,
  132.           call_data_size);
  133.  
  134.     return True;
  135.     }
  136.     else {
  137.     XtAppWarning(XtWidgetToApplicationContext(w),
  138.           "bad request name.  PixmapWidget");
  139.     return False;
  140.     }
  141. }
  142.  
  143. /*
  144.  * Engages the request designated by the current parameter.
  145.  * Returnes TRUE if the request has an engage function and FALSE otherwise.
  146.  */
  147. Boolean Engage(PW, current)
  148.     PixmapWidget PW;
  149.     Cardinal current;
  150. {
  151.     PW->pixmap.current = current;
  152.     
  153.     if (_PWDEBUG)
  154.     fprintf(stderr, "Request: %s\n", 
  155.         PW->pixmap.request_stack[current].request->name);
  156.   
  157.     if (PW->pixmap.request_stack[current].request->engage) {
  158.     (*PW->pixmap.request_stack[current].request->engage)
  159.         ((Widget) PW,
  160.          PW->pixmap.request_stack[current].status,
  161.          PW->pixmap.request_stack[current].request->engage_client_data,
  162.          PW->pixmap.request_stack[current].call_data);
  163.     return True;
  164.     }
  165.     else
  166.     return False;
  167. }
  168.  
  169.  
  170. /*
  171.  * Scans down the request stack removing all requests untill it finds 
  172.  * one to be trapped.
  173.  */
  174. void TrappingLoop(PW)
  175.     PixmapWidget PW;
  176. {
  177.  
  178.     if (_PWDEBUG)
  179.     fprintf(stderr, "Scanning... Current: %d\n", PW->pixmap.current);
  180.     if ((PW->pixmap.current > 0) 
  181.     && 
  182.     (!PW->pixmap.request_stack[PW->pixmap.current--].trap)) {
  183.     PWRemoveRequest((Widget) PW);
  184.     TrappingLoop(PW);
  185.     }
  186.     else
  187.     if (PW->pixmap.cardinal > 0) {
  188.         if (_PWDEBUG)
  189.         fprintf(stderr, "Trapping... Current: %d\n", PW->pixmap.current+1);
  190.         if(!Engage(PW, ++PW->pixmap.current))
  191.         PWTerminateRequest((Widget) PW, True);
  192.     }
  193. }
  194. /*
  195.  * Terimantes the current request and continues with next request if con = TRUE
  196.  * Returnes TRUE if there is any number of requests left on the stack.
  197.  */
  198. #if NeedFunctionPrototypes
  199. Boolean PWTerminateRequest(Widget w, Boolean cont)
  200. #else
  201. Boolean PWTerminateRequest(w, cont)
  202.     Widget w;
  203.     Boolean cont;
  204. #endif
  205. {
  206.     PixmapWidget PW = (PixmapWidget) w;
  207.     
  208.     if (PW->pixmap.current > 0) {
  209.     if (_PWDEBUG)
  210.         fprintf(stderr, "Terminating... Current: %d\n", PW->pixmap.current);
  211.         if (PW->pixmap.request_stack[PW->pixmap.current].request->terminate)
  212.         (*PW->pixmap.request_stack[PW->pixmap.current].request->terminate)
  213.         (w,
  214.          PW->pixmap.request_stack[PW->pixmap.current].status,
  215.          PW->pixmap.request_stack[PW->pixmap.current].request->terminate_client_data,
  216.          PW->pixmap.request_stack[PW->pixmap.current].call_data);
  217.     
  218.     if (cont) {
  219.         if (PW->pixmap.current == PW->pixmap.cardinal)
  220.         TrappingLoop(PW);
  221.         else {
  222.         if (_PWDEBUG)
  223.             fprintf(stderr, "Continuing... Current: %d\n", PW->pixmap.current+1);
  224.         if (!Engage(PW, ++PW->pixmap.current))
  225.             PWTerminateRequest(w, True);
  226.         }
  227.     }
  228.     else
  229.         PW->pixmap.current = 0;
  230.     }
  231.     
  232.     return PW->pixmap.current;
  233. }
  234.  
  235. /*
  236.  * Simple interface to PWTerminateRequest that takes only a widget.
  237.  */
  238. #if NeedFunctionPrototypes
  239. void PWTerminate(Widget w)
  240. #else
  241. void PWTerminate(w)
  242.     Widget w;
  243. #endif
  244. {
  245.     PWTerminateRequest(w, True);
  246. }
  247.  
  248. /*
  249.  * Removes the top request from the request stack. If the request is active
  250.  * it will terminate it.
  251.  * Returns TRUE if the number of requests left on the stack != 0.
  252.  */
  253. #if NeedFunctionPrototypes
  254. Boolean PWRemoveRequest(Widget w)
  255. #else
  256. Boolean PWRemoveRequest(w)
  257.     Widget w;
  258. #endif
  259. {
  260.     PixmapWidget PW = (PixmapWidget) w;
  261.     
  262.     if (PW->pixmap.cardinal > 0) {
  263.     if (_PWDEBUG)
  264.         fprintf(stderr, "Removing... Cardinal: %d\n", PW->pixmap.cardinal);
  265.     if (PW->pixmap.current == PW->pixmap.cardinal)
  266.         PWTerminateRequest(w, False);
  267.     
  268.     if (PW->pixmap.request_stack[PW->pixmap.cardinal].request->remove)
  269.         (*PW->pixmap.request_stack[PW->pixmap.cardinal].request->remove)
  270.         (w,
  271.          PW->pixmap.request_stack[PW->pixmap.cardinal].status,
  272.          PW->pixmap.request_stack[PW->pixmap.cardinal].request->remove_client_data,
  273.          PW->pixmap.request_stack[PW->pixmap.cardinal].call_data);
  274.     
  275.     XtFree(PW->pixmap.request_stack[PW->pixmap.cardinal].status);
  276.     XtFree(PW->pixmap.request_stack[PW->pixmap.cardinal].call_data);
  277.     PW->pixmap.request_stack = (PWRequestStack *)
  278.         XtRealloc((char *)PW->pixmap.request_stack,
  279.          (Cardinal)((--PW->pixmap.cardinal + 1) * sizeof(PWRequestStack)));
  280.     
  281.     return True;
  282.     }
  283.     else 
  284.     return False;
  285. }
  286.  
  287. #if NeedFunctionPrototypes
  288. void PWRemoveAllRequests(Widget w)
  289. #else
  290. void PWRemoveAllRequests(w)
  291.     Widget w;
  292. #endif
  293. {
  294.     while (PWRemoveRequest(w)) {/* removes all requests from the stack */}
  295. }
  296.  
  297. /*
  298.  * Adds the request to the stack and performs engaging ritual.
  299.  * Returns TRUE if the request was found, FALSE otherwise.
  300.  */
  301. #if NeedFunctionPrototypes
  302. Boolean PWEngageRequest(Widget w, PWRequest name, Boolean trap, 
  303.             XtPointer call_data, Cardinal call_data_size)
  304. #else
  305. Boolean PWEngageRequest(w, name, trap, call_data, call_data_size)
  306.     Widget w;
  307.     PWRequest name;
  308.     Boolean trap;
  309.     XtPointer call_data;
  310.     Cardinal call_data_size;
  311. #endif
  312. {
  313.     PixmapWidget PW = (PixmapWidget) w;
  314.     
  315.     if (PWAddRequest(w, name, trap, call_data, call_data_size)) {
  316.     PWTerminateRequest(w, False);
  317.     if (_PWDEBUG)
  318.         fprintf(stderr, "Engaging... Cardinal: %d\n", PW->pixmap.cardinal);
  319.     if (!Engage(PW, PW->pixmap.cardinal))
  320.         PWTerminateRequest(w, True);
  321.     
  322.     return True;
  323.     }
  324.     else
  325.     return False;
  326. }
  327.  
  328. /************************* End of the Request Machine ************************/
  329.  
  330.  
  331.  
  332.  
  333.